#ifndef VECTOR3_HPP
#define VECTOR3_HPP

#include <math.h>

class Vector3 {
private:
public:
	double x, y, z;
	Vector3():x(0), y(0), z(0) {}
	Vector3(double x, double y, double z):x(x), y(y), z(z) {}
	void set(double x, double y, double z) {
		this->x=x;
		this->y=y;
		this->z=z;
	}
	void setx(double x) {
		this->x=x;
	}
	void sety(double y) {
		this->y=y;
	}
	void setz(double z) {
		this->z=z;
	}
	double getx() const { return x; }
	double gety() const { return y; }
	double getz() const { return z; }
	double operator[] (int i) const { if (i==0) return x; if (i==1) return y; if (i==2) return z; return -1;}
	Vector3 add(Vector3 const &vector3) const {
		return Vector3(this->x + vector3.x, this->y + vector3.y, this->z + vector3.z);
	}
	Vector3 operator+(Vector3 const &vector3) const { return add(vector3); }
	Vector3 sub(Vector3 const &vector3) const {
		//std::cout << x << "-" << vector3.x << std::endl;
		//std::cout << y << "-" << vector3.y << std::endl;
		//std::cout << z << "-" << vector3.z << std::endl;
		return Vector3(this->x - vector3.x, this->y - vector3.y, this->z - vector3.z);
	}
	Vector3 operator-(Vector3 const &vector3) const { return sub(vector3); }
	Vector3 mult(double scale) const { return Vector3(x*scale, y*scale, z*scale); }
	Vector3 operator*(double scale) const {return mult(scale);}
	double dot(Vector3 const &vector3) const { 
		return x*vector3.x + y*vector3.y + z*vector3.z;
	}
	Vector3 cross(Vector3 const &vector3) const {
		return Vector3(y*vector3.z - z*vector3.y, z*vector3.x - x*vector3.z, x*vector3.y - y*vector3.x);
	}
	double length() const {
		return sqrt(x*x + y*y + z*z);
	}
	Vector3 normalize() const { 
		double length = this->length();
		return Vector3(x/length, y/length, z/length);
	}
};
#endif